Skip to content

feat(test): installed-host contract matrix with fail-closed version quadruple (#218 stage 3) - #311

Merged
ScriptedAlchemy merged 1 commit into
mainfrom
wave/218-s3-host
Sep 2, 2026
Merged

feat(test): installed-host contract matrix with fail-closed version quadruple (#218 stage 3)#311
ScriptedAlchemy merged 1 commit into
mainfrom
wave/218-s3-host

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Summary

Stage 3 of the #218 contract matrix: an installed-host boundary that discovers and spawns the emitted MCP command from a clean installed layout and records the fail-closed source/built-artifact/installed-artifact/running-process version quadruple.

  • openInstalledHostMcpServer (new src/test/installed.ts): reads the host's emitted MCP document from the installed root, verifies the host manifest, component/resource/hook paths, and every artifact file digest built-vs-installed, expands host root tokens (${CLAUDE_PLUGIN_ROOT}, ${CURSOR_PLUGIN_ROOT}), spawns the installed command over real stdio, and reads the running version only from the live MCP initialize serverInfo. Any missing or disagreeing quadruple value fails closed (version-quadruple / version-digests).
  • runInstalledHostContractMatrix: the shared matrix implementation gains a third boundary via capability flags (no forked check logic); module-backed checks are honestly not-applicable since loading project modules would cross back into the source/build tree. The report carries the quadruple plus evidence metadata: host binary version (observed or honestly unavailable), adapter revision, manifest/schema digest, framework version.
  • Lanes riding the existing feat(test): host-install proof level with real Claude, Codex, and Cursor install proofs (#100 stage 3) #242/test(install): empty-dir packed-tarball host-install proofs for the package-relative installer (#252) #283 machinery and its single fixture build: a deterministic adapter-simulator lane (unconditional), real Claude and Codex lanes through the public install path with --version-observed host binaries, a Cursor lane with its non-interactive session surface recorded honestly, and a fail-closed negative where a tampered installed manifest fails version-digests + version-quadruple.

Deferred (recorded on #218): runtime-instance identity beyond live initialize depends on #269 (WarmRuntimeIdentity).

Gates (local, rebased on be33352 + stage 2)

pnpm build · pnpm typecheck · pnpm lint (0/0) · pnpm test:unit (0 failed) · pnpm test:route-unit (24) · pnpm test:projection (58) · pnpm test:host-install (6/6, 0 skipped — real Claude + Codex lanes ran) · pnpm test:packed (26 passed / 1 skipped).

Prove emitted host layouts through live stdio sessions and fail closed when source, built, installed, or running versions drift.
@changeset-bot

changeset-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6b8bb0c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agent-bundle Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T19:25:54.003345Z 6b8bb0c PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@pkg-pr-new

pkg-pr-new Bot commented Sep 2, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@311
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@311
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@311

commit: 6b8bb0c

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6b8bb0c57e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +415 to +417
if (expandedCommand.length === 0 || discovered.name.length === 0) throw installedFailure(failures);
const client = new Client({ name: 'agent-bundle-installed-host-proof', version: '1.0.0' });
const transport = new StdioClientTransport({

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject integrity failures before starting the process

If an installed .mcp.json is tampered to run something such as node /tmp/evil.mjs, the digest check records a failure but this guard only rejects an empty command or server name; client.connect subsequently executes the altered command, and the helper throws only after initialization. Since this API is explicitly a fail-closed installed-artifact verifier, all accumulated preflight failures must be rejected before constructing/connecting the transport.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 54e4c4c09: all accumulated static integrity failures now throw before the MCP client or transport is constructed/connected. A regression tampers the installed command with an executable marker and proves it is never launched. Merged via #318.

Comment on lines +310 to +312
if (resourceFiles.length === 0) {
failures.push({ check: 'resources', reason: 'artifact manifest declared no installed resources' });
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow artifacts without resource components

For a valid MCP-only plugin with no assets, skills, or commands, resourceFiles is empty and the opener always reports a resources violation. These component trees are optional, so absence should pass while declared resource files should still be checked; otherwise the new public helper cannot test a common generated-plugin shape.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 54e4c4c09: a manifest with zero declared resource components now passes the resources check, while every declared resource still receives the existing installed-file verification. The regression removes all resource declarations from a cloned artifact manifest. Merged via #318.

Comment on lines +357 to +359
const hooks = commandStrings(hookDocument);
if (hooks.length === 0) {
failures.push({ check: 'hook-commands', reason: 'installed hook document exposed no commands' });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow generated plugins without hooks

When a project declares an MCP server but no hooks, the adapters legitimately omit hooks/hooks.json and the artifact hook index contains no entries for that target, yet this code unconditionally fails because it found no commands. Hook validation must be conditional on hooks being declared; otherwise every hookless installed plugin is rejected before its MCP contract matrix can run.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 54e4c4c09: the artifact hook index is parsed first, and installed hook documents/targets are required only when that target declares hooks. Invalid indexes still fail closed, and declared hooks retain per-file checks. Merged via #318.

Comment on lines +475 to +477
proofLevel: proofLevelLabel(HOST_INSTALL_PROOF_LEVEL),
sessionEvidence: options.sessionEvidence
?? 'adapter-simulated discovery and stdio spawn from an isolated installed root',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not label simulated staging as real host installation

With the documented adapter-simulator path—or a direct opener call using its default sessionEvidence—the bundle is only copied and its MCP command is spawned, but this label expands to a claim that the bundle went through a real host's public install path and that registration was observed via the host CLI. That overstates the evidence and can corrupt consumers' proof-level results; simulated sessions need a truthful qualifier/level instead of this existing real-host label.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 54e4c4c09: omitted/defaulted sessionEvidence now selects the distinct simulated proof level and label throughout observation, provenance, matrix failures, and reports; explicit real-host evidence remains host-install. Merged via #318.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant